import { Component, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms'
import { of } from 'rxjs'
import { concatMap, map } from 'rxjs/operators'
import { NzMessageService } from 'ng-zorro-antd'

import { UserService } from 'app/routes/user/user.service'
import { UserAlinterService } from 'app/routes/user/user-alinter.service'
import { IChangePassword } from '@shared/interfaces/user'
import { makeAllControlDirty, MustMatch, encryptPassword } from 'app/utils/helpers'
import { passwordReg } from 'app/utils/contraints'
import { I18NService } from '@core'

@Component({
  selector: 'app-edit-password',
  templateUrl: './edit-password.component.html',
  styleUrls: ['./edit-password.component.less'],
  providers: [{ provide: UserService, useClass: UserAlinterService }],
})
export class EditPasswordComponent implements OnInit {
  validateForm: FormGroup
  userName: string
  isLoading = false

  constructor(
    private msg: NzMessageService,
    private fb: FormBuilder,
    private userService: UserService,
    private route: ActivatedRoute,
    private router: Router,
    private i18n: I18NService
  ) {}

  ngOnInit(): void {
    this.initialData()
    this.setupForm()
  }

  initialData() {
    this.userName = this.getUsername()
    if (!this.userName) {
      this.userService.current().subscribe(user => {
        this.userName = user.username
      })
    }
  }

  getUsername(): string {
    return this.route.snapshot.params['id']
  }

  isChangeOtherPassword(): boolean {
    return Boolean(this.getUsername())
  }

  setupForm() {
    const fb = {
      passwordOld: [null, [Validators.required]],
      password: [null, [Validators.required, Validators.minLength(8), Validators.pattern(passwordReg)]],
      passwordCF: [null, [Validators.required, Validators.minLength(8), Validators.pattern(passwordReg)]],
    }
    // 更改别人密码不需要 original password
    if (this.isChangeOtherPassword()) {
      delete fb.passwordOld
    }
    this.validateForm = this.fb.group(fb, {
      validator: MustMatch('password', 'passwordCF'),
    })
  }

  submit(): void {
    const valid = this.validateForm.valid
    if (!valid) {
      makeAllControlDirty(this.validateForm)
      return
    }
    this.isLoading = true
    const params = this.getApiParams()
    of(params)
      .pipe(
        concatMap(para => {
          if (this.isChangeOtherPassword()) {
            return this.userService.changePassword(this.userName, para).pipe(map(() => true))
          } else {
            return this.userService.changeMePassword(para)
          }
        }),
      )
      .subscribe(
        () => {
          this.msg.success(this.i18n.fanyi('USER.UPDATE_PASSWORD.SUCCESS'))
          this.router.navigate(['../'], { relativeTo: this.route })
          this.isLoading = false
        },
        () => {
          this.msg.error(this.i18n.fanyi('USER.UPDATE_PASSWORD.FAILED'))
          this.isLoading = false
        },
      )
  }

  getApiParams(): IChangePassword {
    const { passwordOld, password: passwordNew } = this.validateForm.value
    const params = {
      passwordNew: encryptPassword(passwordNew),
    }
    if (!this.isChangeOtherPassword()) {
      params['passwordOld'] = encryptPassword(passwordOld)
    }
    return params
  }

  get passwordOldCtrl(): FormControl {
    return this.validateForm.get('passwordOld') as FormControl
  }

  get passwordCtrl(): FormControl {
    return this.validateForm.get('password') as FormControl
  }

  get passwordCFCtrl(): FormControl {
    return this.validateForm.get('passwordCF') as FormControl
  }
}
